﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace Liju.Common
{
    public class SerialLock
    {
        private SerialPort _serialPort;

        // 构造函数，初始化串口参数并打开串口连接
        public SerialLock(string portName)
        {
            _serialPort = new SerialPort
            {
                PortName = portName,
                BaudRate = 57600,
                DataBits = 8,
                StopBits = StopBits.One,
                Parity = Parity.None,
                Handshake = Handshake.None,
                ReadTimeout = 1000 // 读超时1秒
            };

            OpenSerialConnection();
        }

        // 打开串口连接的方法
        private void OpenSerialConnection()
        {
            try
            {
                _serialPort.Open();
                Console.WriteLine($"成功连接到 {_serialPort.PortName}，波特率为 {_serialPort.BaudRate}。");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"打开串口时出错: {ex.Message}");
            }
        }

        // 关闭串口连接的方法
        public void CloseConnection()
        {
            if (_serialPort != null && _serialPort.IsOpen)
            {
                _serialPort.Close();
                Console.WriteLine($"串口 {_serialPort.PortName} 已关闭。");
            }
        }

        // 发送数据的方法
        public void SendData(byte [] data)
        {
            if (_serialPort != null && _serialPort.IsOpen)
            {
                _serialPort.Write(data,0,data.Length);
                Console.WriteLine($"数据已发送: {data}");
            }
        }

        // 接收数据的方法，返回字节数组
        public byte[] ReceiveData(int length)
        {
            if (_serialPort != null && _serialPort.IsOpen)
            {
                try
                {
                    
                    byte[] receivedData = new byte[length];
                    Thread.Sleep(100);
                    _serialPort.Read(receivedData, 0, length);
                    Console.WriteLine($"收到的数据: {BitConverter.ToString(receivedData)}");
                    return receivedData;
                }
                catch (TimeoutException)
                {
                    Console.WriteLine("读取操作超时。");
                    return null;
                }
            }
            else
            {
                Console.WriteLine("串口连接未打开。");
                return null;
            }
        }

        // 析构函数，类销毁时自动关闭串口连接
        ~SerialLock()
        {
            CloseConnection();
        }

        /// <summary>
        /// 查询门锁信息，返回锁状态，返回4个锁int数组，0是关闭1是开启,2为异常
        /// </summary>
        /// <returns></returns>
        public void QueryDeviceInfo( out int [] resultstat)
        {
            byte[] command = { 0xFF, 0x01, 0x00, 0x00, 0x00, 0x01 };
            SendData(command);
            // 接收设备信息响应
            byte[] response = ReceiveData(6);
            if (response != null)
            {
                resultstat = ParseDeviceInfoResponse(response);
               
            }
            else
            {
                resultstat = new int[4] { 2,2,2,2 };
            }       

        }

        /// <summary>
        /// 开锁函数返回 0成功1失败
        /// </summary>
        /// <param name="lockNumber">锁编号</param>
        /// <param name="holdTime">开锁保持时间100毫秒单位</param>
        public int ControlLock(byte lockNumber, ushort holdTime)
        {
            

            // 将时间转换为单位为100ms
            int unlockTimeUnits = holdTime / 100;

            // 高字节
            byte highByte = (byte)(unlockTimeUnits / 256);

            // 低字节
            byte lowByte = (byte)(unlockTimeUnits % 256);
            // 计算校验码（功能码加上3字节数据内容的和，取低8位）
            byte checksum = (byte)((0x03 + lockNumber + highByte + lowByte) % 256);

            int result = 1;
            byte[] command = {
            0xFF,
            0x03,
            lockNumber,
            highByte,
          lowByte,
            checksum
        };
                SendData(command);
            // 接收设备信息响应
            byte[] response = ReceiveData(6);
            if (response != null)
            {
                result = ParseControlLockResponse(response);
              
            }
            else
            {
                result =1;

            }
            return result;

        }

        
        // 解析设备信息返回的数据
        public int [] ParseDeviceInfoResponse(byte[] data)
        {
            int[] stat = new int[4];
            if (data.Length == 6 && data[0] == 0xFF && data[1] == 0x02)
            {
                int softwareVersion = data[2];
                byte lockState = data[3];

                // 使用掩码和位操作解析各个锁的状态
                stat[0] = (lockState & 0x01) != 0 ? 1 : 0; // 锁1状态
                stat[1] = (lockState & 0x02) != 0 ? 1 : 0; // 锁2状态
                stat[2] = (lockState & 0x04) != 0 ? 1 : 0; // 锁3状态
                stat[3] = (lockState & 0x08) != 0 ? 1 : 0; // 锁4状态
                return stat;
            }
            else
            {
                Console.WriteLine("无效的设备信息响应。");
                stat = new int[4] { 2, 2, 2, 2 };
                return stat;
            }
        }

        // 解析控锁返回的数据
        public int ParseControlLockResponse(byte[] data)
        {
            if (data.Length == 6 && data[0] == 0xFF && data[1] == 0x04)
            {
                int result = data[2];
               
                Console.WriteLine(result == 0 ? "控锁成功" : "控锁失败");
                return result;

            }
            else
            {
                Console.WriteLine("无效的控锁响应。");
                return 1;
            }
        }

        // 解析门锁异常应答的数据
        public void ParseErrorResponse(byte[] data)
        {
            if (data.Length == 6 && data[0] == 0xFF && data[1] == 0xF0)
            {
                int errorCode = data[2];
                byte receivedHeader = data[3];
                byte receivedFunctionCode = data[4];
                byte receivedChecksum = data[5];
                Console.WriteLine($"错误代码: {errorCode}, 收到的帧头: {receivedHeader}, 收到的功能码: {receivedFunctionCode}, 收到的校验码: {receivedChecksum}");
            }
            else
            {
                Console.WriteLine("无效的错误响应。");
            }
        }
    }
}
